package qc.module.qms.api.job;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import qc.common.core.enums.DataManagementTypeEnum;
import qc.common.core.exception.QCPromptException;
import qc.common.core.json.JsonParserUtil;
import qc.common.core.utils.DateUtil;
import qc.module.platform.dto.dbTable.DBTableFullDto;
import qc.module.qms.api.RestTemplatePlatform;
import qc.module.qms.dto.exchange.category.ExchangeCategoryDto;
import qc.module.qms.dto.station.StationDto;
import qc.module.qms.entity.ExchangeLog;
import qc.module.qms.service.QmsStationService;
import qc.module.qms.service.exchange.ExchangeCategoryService;
import qc.module.qms.service.exchange.ExchangeDataService;
import qc.module.qms.service.exchange.ExchangeLogService;
import qc.module.qms.service.ynsyjpt.YnsyjptPptnDataGenerator;
import qc.module.qms.service.ynsyjpt.YnsyjptRsvrDataGenerator;
import tech.powerjob.worker.core.processor.ProcessResult;
import tech.powerjob.worker.core.processor.TaskContext;
import tech.powerjob.worker.core.processor.sdk.BasicProcessor;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

/**
 * 交换数据人工任务/操作处理器
 *
 * @author QuCheng Tech
 * @since 2024/9/25
 */
@Component
public class ExchangeDataManualTaskProcessor implements BasicProcessor {
    private ExchangeCategoryService categoryService;
    private QmsStationService stationService;
    private ExchangeDataService exchangeDataService;
    private ExchangeLogService exchangeLogService;
    //不同数据分类的数据生成器
    private YnsyjptRsvrDataGenerator ynsyjptRsvrDataGenerator;
    private YnsyjptPptnDataGenerator ynsyjptPptnDataGenerator;

    @Autowired
    public void setExchangeCategoryService(ExchangeCategoryService categoryService) {
        this.categoryService = categoryService;
    }

    @Autowired
    public void setExchangeStationService(QmsStationService stationService) {
        this.stationService = stationService;
    }

    @Autowired
    public void setExchangeDataService(ExchangeDataService exchangeDataService) {
        this.exchangeDataService = exchangeDataService;
    }

    @Autowired
    public void setExchangeLogService(ExchangeLogService exchangeLogService) {
        this.exchangeLogService = exchangeLogService;
    }

    @Autowired
    public void setYnsyjptRsvrDataGenerator(YnsyjptRsvrDataGenerator ynsyjptRsvrDataGenerator) {
        this.ynsyjptRsvrDataGenerator = ynsyjptRsvrDataGenerator;
    }

    @Autowired
    public void setYnsyjptPptnDataGenerator(YnsyjptPptnDataGenerator ynsyjptPptnDataGenerator) {
        this.ynsyjptPptnDataGenerator = ynsyjptPptnDataGenerator;
    }

    @Autowired
    private RestTemplatePlatform restTemplatePlatform;

    //静态定义--一次获取人工任务的数量
    public final int getManualTaskCount = 10;

    @Override
    public ProcessResult process(TaskContext taskContext) throws Exception {
        Date now = DateUtil.getNowDate();

        //获取人工处理的任务，获取全部数据分类
        List<ExchangeLog> tasks = exchangeLogService.getNeedExecuteManualLogs(0x0, getManualTaskCount);
        if (tasks != null && tasks.size() > 0x0) {
            for (ExchangeLog task : tasks) {
                String logId = task.getLogid();
                boolean taskExecuteSuccess = false;
                String taskExecuteInfo = null;
                int categoryId = task.getCid();
                StationDto station = stationService.get(task.getStcd());
                System.out.println("交换数据人工任务/操作处理，处理logId=" + logId + "，站点编码=" + task.getStcd() + "，站点名称=" + station.getStnm() + "，时间段=" + DateUtil.getDateTimeString(task.getBegintm()) + "~~" + DateUtil.getDateTimeString(task.getEndtm()) + "，操作类型=" + task.getOptype().toString());
                //均需要根据数据分类获取数据库连接信息
                ExchangeCategoryDto category = categoryService.get(categoryId);
                System.out.println("交换数据人工任务/操作处理，处理logId=" + logId + "，获取数据分类信息，category=" + category.getTablecode() + " getParams=" + category.getParams());
                if (category != null && StringUtils.isNotBlank(category.getTablecode())) {
                    //根据数据库表编码获取完整信息，再从信息中获取sql语句、查询数据库连接信息和列信息
                    DBTableFullDto tableFullInfo = restTemplatePlatform.getDbTableFullInfo(category.getTablecode());
                    //数据库连接信息
                    String dbUrl = "";
                    String dbUser = "";
                    String dbPassword = "";
                    if (tableFullInfo != null) {
                        if (tableFullInfo.getDb() != null) {
                            //解析数据库连接信息
                            String dbConJsonString = tableFullInfo.getDb().getCon();
                            if (StringUtils.isNotBlank(dbConJsonString)) {
                                //Json对象进行获取
                                dbUrl = JsonParserUtil.getString(dbConJsonString, "url");
                                dbUser = JsonParserUtil.getString(dbConJsonString, "user");
                                dbPassword = JsonParserUtil.getString(dbConJsonString, "password");
                            }
                        }
                    }

                    //判断操作类型：如果时重新生成写入需要根据不同的数据分类ID进行不同的处理，如果是修改或删除可以直接执行SQL
                    if (task.getOptype() == DataManagementTypeEnum.INSERT) {
                        //数据重新生成，写入数据操作
                        //根据数据分类ID调用不同的方法进行处理
                        if (categoryId == 0x1 || categoryId == 0x2) {
                            //省汇集平台，需要获取数据分类中的原始数据表信息
                            //原始数据表，需要固定指定表名，或者在数据分类参数配置中指定
                            //2024-9-29，原始数据表由DeviceTimingDataRecord修改为MS_QZJ_SRCDATA；计讯接收软件接收到数据后写入DeviceTimingDataRecord，由触发器触发到MS_QZJ_SRCDATA
                            //原始数据使用MS_QZJ_SRCDATA表可以从其他接收数据库中直接将数据导入以进行数据处理；如南康河中云服务器接收数据中断，从南康河电站接收的前置机数据库中导入缺失时间段内的数据；
                            //String defaultSrcDbTableCode="DeviceTimingDataRecord";
                            String defaultSrcDbTableCode = "MS_QZJ_SRCDATA";
                            String sourceDbTableCode = null;
                            if (category != null && StringUtils.isNotBlank(category.getParams())) {
                                sourceDbTableCode = JsonParserUtil.getString(category.getParams(), "原始数据来源表");
                            }
                            if (StringUtils.isBlank(sourceDbTableCode))
                                sourceDbTableCode = defaultSrcDbTableCode;
                            //根据数据库表编码获取完整信息，再从信息中获取sql语句、查询数据库连接信息和列信息
                            DBTableFullDto srcTableFullInfo = restTemplatePlatform.getDbTableFullInfo(sourceDbTableCode);
                            if (categoryId == 0x1) {
                                //云南省汇集平台，水库实时水位
                                try {
                                    taskExecuteInfo = ynsyjptRsvrDataGenerator.generate(station, task.getBegintm(), task.getEndtm(), tableFullInfo, srcTableFullInfo);

                                    //执行完成的都设置为执行成功
                                    taskExecuteSuccess = true;
                                } catch (QCPromptException ex) {
                                    taskExecuteInfo = ex.getMessage();
                                } catch (SQLException ex) {
                                    taskExecuteInfo = ex.getMessage();
                                }
                            } else if (categoryId == 0x2) {
                                //云南省汇集平台，水库实时雨量
                                try {
                                    taskExecuteInfo = ynsyjptPptnDataGenerator.generate(station, task.getBegintm(), task.getEndtm(), tableFullInfo, srcTableFullInfo);

                                    //执行完成的都设置为执行成功
                                    taskExecuteSuccess = true;
                                } catch (QCPromptException ex) {
                                    taskExecuteInfo = ex.getMessage();
                                } catch (SQLException ex) {
                                    taskExecuteInfo = ex.getMessage();
                                }
                            }
                        } else {
                            //其他数据交换判断处理
                            //执行完成的都设置为执行成功
                            taskExecuteSuccess = true;
                        }
                    } else if (task.getOptype() == DataManagementTypeEnum.UPDATE) {
                        try {
                            //数据修改或删除操作，根据sql进行执行
                            taskExecuteSuccess = exchangeDataService.update(dbUrl, dbUser, dbPassword, task.getSqlstr(), new String[]{task.getStcd()}, task.getBegintm(), task.getEndtm());
                        } catch (Exception ex) {
                            taskExecuteInfo = ex.getMessage();
                        }
                    } else if (task.getOptype() == DataManagementTypeEnum.DELETE) {
                        try {
                            //数据修改或删除操作，根据sql进行执行
                            taskExecuteSuccess = exchangeDataService.delete(dbUrl, dbUser, dbPassword, task.getSqlstr(), new String[]{task.getStcd()}, task.getBegintm(), task.getEndtm());
                        } catch (Exception ex) {
                            taskExecuteInfo = ex.getMessage();
                        }
                    } else {
                        //任务的操作类型错误，只能是生成写入、修改或删除
                        taskExecuteInfo = "任务操作类型错误，只能为写入、修改或删除操作。";
                    }
                } else {
                    //数据分类ID错误，或者未配置对应的数据库表编码
                    taskExecuteInfo = "数据分类ID错误，或者未配置对应的数据库表编码。";
                }

                //修改人工操作任务的执行结果
                String setTaskResult = exchangeLogService.setExecuteResult(logId, taskExecuteSuccess, taskExecuteInfo);
                if (StringUtils.isBlank(setTaskResult)) {
                    //修改执行结果成功
                    System.out.println("交换数据人工任务/操作处理，处理logId=" + logId + "，修正执行结果信息成功。");
                } else {
                    //修改执行结果失败
                    System.out.println("交换数据人工任务/操作处理，处理logId=" + logId + "，修正执行结果信息失败，" + setTaskResult);
                }
            }
        }

        return new ProcessResult(true, "交换数据人工任务处理成功");
    }
}
